//
//  YZCollectionViewWaterfallLayout.m
//  CollectionTest
//
//  Created by yuze on 2016/10/20.
//  Copyright © 2016年 yuze. All rights reserved.
//

#import "YZCollectionViewWaterfallLayout.h"

/// 列数
static const CGFloat ColumCount = 3.0;
/// 每一列间距
static const CGFloat ColumMargin = 10.0;
/// 每一行间距
static const CGFloat RowMargin = 10.0;
/// 边缘间距
static const UIEdgeInsets DefaultEdgeInsets = {10, 10, 10, 10};

@interface YZCollectionViewWaterfallLayout ()

/// 布局属性数组
@property (nonatomic, strong) NSMutableArray *attrsArray;
/// 存放所有列的当前高度
@property (nonatomic, strong) NSMutableArray *columnHeights;

@end

@implementation YZCollectionViewWaterfallLayout

#pragma mark -- override method

- (void)prepareLayout
{
    [super prepareLayout];
    
    // 清空高度数组，重新计算每一列的高度
    [self.columnHeights removeAllObjects];
    for (NSUInteger i = 0; i < self.columCount; i++) {
        [self.columnHeights addObject:@(self.defaultEdgeInsets.top)];
    }
    
    // 清空cell属性，重新添加cell属性
    [self.attrsArray removeAllObjects];
    NSInteger count = [self.collectionView numberOfItemsInSection:0];
    for (NSUInteger i = 0; i < count; i++) {
        
        /// 根据indexPath 获取cell属性
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
        UICollectionViewLayoutAttributes *attribute = [self layoutAttributesForItemAtIndexPath:indexPath];
        [self.attrsArray addObject:attribute];
    }
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes *attr = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
    
    // 找出最短的一列
    NSUInteger destColumn = 0;
    CGFloat minColumnHeight = [self.columnHeights[0] doubleValue];
    
    for (NSUInteger i = 1; i < self.columCount; i++) {
        
        CGFloat columnHeight = [self.columnHeights[i] doubleValue];
        if (minColumnHeight > columnHeight) {
            
            minColumnHeight = columnHeight;
            destColumn = i;
        }
    }
    
    CGFloat w = (self.collectionView.frame.size.width
                 - self.defaultEdgeInsets.left
                 - self.defaultEdgeInsets.right
                 - (self.columCount - 1) * self.columMargin) / self.columCount;
    CGFloat h = [self.delegate waterfallLayout:self heightForRowAtIndex:indexPath.item itemWidth:w];
    CGFloat x = self.defaultEdgeInsets.left + destColumn*(w + self.columMargin);
    CGFloat y = minColumnHeight ;
    
    if (y != self.defaultEdgeInsets.top) {
        y += self.rowMargin;
    }
    
    attr.frame = CGRectMake(x, y, w, h);
    
    self.columnHeights[destColumn] = @(y+ h);
    return attr;
}

- (NSArray<UICollectionViewLayoutAttributes *> *)layoutAttributesForElementsInRect:(CGRect)rect
{
    return self.attrsArray;
}

- (CGSize)collectionViewContentSize
{
    
    CGFloat maxHeight = [self.columnHeights[0] doubleValue];
    for (int i = 1; i < self.columCount; i++) {
        
        CGFloat value = [self.columnHeights[i] doubleValue];
        if (maxHeight < value) {
            
            maxHeight = value;
        }
    }
    return CGSizeMake(0, maxHeight+self.defaultEdgeInsets.bottom);
}

#pragma mark -- private method

- (NSInteger)columCount
{
    if ([self.delegate respondsToSelector:@selector(cloumnCountInWaterfallLayout:)]) {
        return [self.delegate cloumnCountInWaterfallLayout:self];
    } else {
        return ColumCount;
    }
}

- (CGFloat)columMargin
{
    if ([self.delegate respondsToSelector:@selector(columMarginInWaterfallLayout:)]) {
        return [self.delegate columMarginInWaterfallLayout:self];
    } else {
        return ColumMargin;
    }
}

- (CGFloat)rowMargin
{
    if ([self.delegate respondsToSelector:@selector(rowMarginInWaterfallLayout:)]) {
        return [self.delegate rowMarginInWaterfallLayout:self];
    } else {
        return RowMargin;
    }
}

- (UIEdgeInsets)defaultEdgeInsets
{
    if ([self.delegate respondsToSelector:@selector(edgeInsetInWaterfallLayout:)]) {
        return [self.delegate edgeInsetInWaterfallLayout:self];
    } else {
        return DefaultEdgeInsets;
    }
}

#pragma  mark -- getter setter

- (NSMutableArray *)attrsArray
{
    if (_attrsArray == nil) {
        
        _attrsArray = [[NSMutableArray alloc] init];
    }
    
    return _attrsArray;
}

- (NSMutableArray *)columnHeights
{
    if (_columnHeights == nil) {
        _columnHeights = [[NSMutableArray alloc] init];
    }
    
    return _columnHeights;
}

@end
